package com.dyp.oauth2_demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;


@Configuration
@EnableWebSecurity
public class ResourceSecurityConfig {
    /**
     * 用于认证的Spring Security过滤器链。
     *
     * 虽然每个 SecurityFilterChain 方法都接收 HttpSecurity http 参数，但 Spring会为每个链创建独立的配置上下文。
     * 这些 HttpSecurity 实例底层共享同一个 SecurityFilterChain 注册机制，但规则相互隔离。
     * 每次方法调用时，Spring会注入一个新的 HttpSecurity 实例，确保各链的配置独立性。
     */
    @Bean
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        //csrf漏洞防御
//        http.csrf(Customizer.withDefaults()); //默认实现实际什么都没做

        http
                // 配置角色，进行权接口权限的分配
                .authorizeHttpRequests(authz -> authz
                        .requestMatchers("/assets/**","/webjars/**","/actuator/**","/oauth2/**","/login").permitAll()
                        .anyRequest().authenticated())
                .cors(Customizer.withDefaults())
                .csrf(AbstractHttpConfigurer::disable)
                .formLogin(Customizer.withDefaults());

        return http.build();
    }

    /**
     * 用户信息服务(配置用户账号、密码、角色)
     * @param passwordEncoder 密码加密器
     * @return 在内存用户详细信息管理器中
     */
    @Bean
    public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
        UserDetails user = User.withUsername("user")
                .password(passwordEncoder.encode("123456"))
                .roles("USER")
                .build();

        UserDetails admin = User.withUsername("admin")
                .password(passwordEncoder.encode("123456"))
                .roles("USER", "ADMIN")
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }
}
